package com.zhhs;

import com.zhhs.common.utils.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.FileSystemResourceLoader;
import org.springframework.core.io.ResourceLoader;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
import org.springframework.util.ResourceUtils;

import javax.sql.DataSource;
import java.io.File;
import java.io.IOException;
import java.util.List;

/**
 * @version 1.0
 * @description: 项目环境, 执行一些初始配置, 获取项目跟路径
 * 注意:所有的@PostConstruct都需要在此bean构建成功后执行,需要在有@PostConstruct注解的类上加注解 @DependsOn("projectEnvironment")
 * @author: 小虎
 * @date: Created in 2023/4/27 10:18
 */
public class ProjectEnvironment {
    private static final Logger log = LoggerFactory.getLogger(ProjectEnvironment.class);
    private ResourceLoader resourceLoader;
    private JdbcTemplate jdbcTemplate;

    public ProjectEnvironment(ResourceLoader resourceLoader, JdbcTemplate jdbcTemplate) {
        this.resourceLoader = resourceLoader;
        this.jdbcTemplate = jdbcTemplate;
        init();
    }

    /**
     * 获取项目根路径
     */
    public String getProjectRootPath() throws IOException {
        final String classes = "target\\classes";
        final String lib = "lib";
        File rootDir = ResourceUtils.getFile(String.valueOf(resourceLoader.getResource("classpath:").getFile()));
        String projectPath = rootDir.toPath().toString();
        if (projectPath.endsWith(classes)) {
            return projectPath.replace(classes, "");
        }
        if (projectPath.endsWith(lib)) {
            return projectPath.replace(lib, "");
        }
        throw new RuntimeException("failed to obtain the project root path !!!");
    }

    private void init() {
        try {
            checkDatabase();
            //...
            //wx
            //pay
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("failed to load sql !!!");
        }
    }

    /**
     * 检查数据库脚本
     */
    private void checkDatabase() throws Exception {
        String sqlPath = getProjectRootPath() + "sql";
        log.info("sql path:{}", sqlPath);
        File file = new File(sqlPath);
        if (!file.isDirectory()) {
            throw new RuntimeException("the sql directory does not exist : " + sqlPath);
        }
        File[] files = file.listFiles((dir, name) -> name.endsWith(".sql"));
        String catalog = jdbcTemplate.getDataSource().getConnection().getCatalog();
        String sql = "SELECT count(1) FROM information_schema.tables WHERE table_name = 'sys_sql_version'  and table_schema ='"+catalog+"'";
        int count = jdbcTemplate.queryForObject(sql, Integer.class);
        if (count <= 0) {
            String _sys_sql_version_ = "create table sys_sql_version (`script_name` varchar ( 1000 ) default null comment '脚本名称',`execute_date` varchar ( 100 ) default null comment '执行时间',`status` varchar ( 100 ) default null comment '执行状态' )";
            jdbcTemplate.execute(_sys_sql_version_);
        }
        String select = "select script_name from sys_sql_version where status = '成功'";
        List<String> version = jdbcTemplate.queryForList(select, String.class);
        String insert = "insert into sys_sql_version (script_name, execute_date, status) values ('%s', '%s', '%s');";
        for (File sqlFile : files) {
            String name = sqlFile.getName();
            if (!version.contains(name)) {
                try {
                    loadData(sqlFile.getAbsolutePath());
                    jdbcTemplate.execute(String.format(insert, name, DateUtils.getTime(), "成功"));
                    log.info("{}加载完成!", name);
                } catch (Exception e) {
                    log.error("{}加载失败!", name);
                    jdbcTemplate.execute(String.format(insert, name, DateUtils.getTime(), "失败"));
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 加载sql文件
     */
    private void loadData(String filePath) {
        FileSystemResourceLoader resourceLoader = new FileSystemResourceLoader();
        ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
        populator.addScript(resourceLoader.getResource("file:" + filePath));
        populator.execute(jdbcTemplate.getDataSource());
    }
}
